package middleware

import (
	"mime"
	"net/http"

	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
)

type DefaultHandlerResponse struct {
	Code    int         `json:"code"    dc:"Error code"`
	Message string      `json:"message" dc:"Error message"`
	Data    interface{} `json:"data"    dc:"Result data for certain request according API definition"`
}

const (
	contentTypeEventStream  = "text/event-stream"
	contentTypeOctetStream  = "application/octet-stream"
	contentTypeMixedReplace = "multipart/x-mixed-replace"
)

var (
	// 响应流类型
	streamContentType = []string{contentTypeEventStream, contentTypeOctetStream, contentTypeMixedReplace}
)

func ResponseHandler(r *ghttp.Request) {
	r.Middleware.Next()
	// 有自定义缓冲区内容，然后退出当前处理程序。
	if r.Response.BufferLength() > 0 {
		return
	}

	// 如果是流响应，则不输出普通响应内容。
	mediaType, _, _ := mime.ParseMediaType(r.Response.Header().Get("Content-Type"))
	for _, ct := range streamContentType {
		if mediaType == ct {
			return
		}
	}

	var (
		msg     string
		err     = r.GetError()
		res     = r.GetHandlerResponse()
		code    = gerror.Code(err).Code()
		errCode = gerror.Code(err)
	)
	if err != nil {
		if errCode == gcode.CodeNil {
			errCode = gcode.CodeInternalError
			code = gcode.CodeInternalError.Code()
		}
		msg = err.Error()
	} else {
		msg = http.StatusText(r.Response.Status)
		if r.Response.Status > 0 && r.Response.Status != http.StatusOK {
			switch r.Response.Status {
			case http.StatusNotFound:
				code = http.StatusNotFound
				errCode = gcode.CodeNotFound
			case http.StatusForbidden:
				code = http.StatusForbidden
				errCode = gcode.CodeNotAuthorized
			default:
				code = http.StatusInternalServerError
				errCode = gcode.CodeUnknown
			}
			// 发生时返回更详细的错误信息
			err = gerror.NewCode(errCode, msg)
			r.SetError(err)
		} else {
			code = http.StatusOK
		}
	}

	r.Response.WriteJson(DefaultHandlerResponse{
		Code:    code,
		Message: msg,
		Data:    res,
	})
}
